﻿using System;
using System.IO;
using Rebex.Mail;

namespace MailConverter
{
    /// <summary>
    /// 在不同邮件文件格式之间进行转换.
    /// </summary>
    class Program
	{
		// =========================
		// - 应用程序参数 -
		// =========================
		static MailFormat TargetFormat;
		static string SourcePath;
		static string TargetDir;
		static bool Ignore = false;
        // =========================

        /// <summary>
        /// 应用程序入口点.
        /// </summary>
        [STAThread]
		static int Main(string[] args)
		{
			try
			{
				if (TryParseArguments(args))
				{
					return Run();
				}
				else
				{
					ShowHelp();
					return 1;
				}
			}
			catch (Exception ex)
			{
				Console.WriteLine("异常信息:");
				Console.WriteLine(ex.ToString());
				return 2;
			}
		}

		/// <summary>
		/// 主程序.
		/// </summary>
		private static int Run()
		{
			if (!Directory.Exists(TargetDir))
			{
				Console.WriteLine("输出路径 '{0}' 不存在.", TargetDir);
				return 1;
			}

			string sourceDir = Path.GetDirectoryName(SourcePath);
			if (string.IsNullOrEmpty(sourceDir))
				sourceDir = @".\";

			if (!Directory.Exists(sourceDir))
			{
				Console.WriteLine("选择目录 '{0}' 不存在.", sourceDir);
				return 1;
			}

			string sourcePattern = Path.GetFileName(SourcePath);
			string[] sourceFiles = Directory.GetFiles(sourceDir, sourcePattern, SearchOption.TopDirectoryOnly);
			if (sourceFiles.Length <= 0)
			{
				Console.WriteLine("没有 \n  与目录 '{0}'\n  和文件相匹配 '{1}'.", sourceDir, sourcePattern);
				return 1;
			}

			int returnCode = 0;
			foreach (string sourceFile in sourceFiles)
			{
				try
				{
					ConvertSingleFile(sourceFile, TargetFormat, TargetDir);
					continue;
				}
				catch (MailException ex)
				{
					Console.WriteLine("转换失败:");
					Console.WriteLine(ex.Message);
				}
				catch (Exception ex)
				{
					Console.WriteLine("转换失败:");
					Console.WriteLine(ex.ToString());
				}

				returnCode = 2;

				if (Ignore)
					continue;
				else
					break;
			}

			return returnCode;
		}

        /// <summary>
        /// 显示帮助信息.
        /// </summary>
        private static void ShowHelp()
		{
			string applicationName = AppDomain.CurrentDomain.FriendlyName;
			Console.WriteLine("=====================================================================");
			Console.WriteLine(" {0} ", applicationName);
			Console.WriteLine("=====================================================================");
			Console.WriteLine();
			Console.WriteLine("在不同邮件格式之间进行转换.");
			Console.WriteLine();
			Console.WriteLine("语法:");
			Console.WriteLine(" MailConverter.exe to-msg|to-mime [--ignore] <输入目录 或 掩码> <输出目录>");
			Console.WriteLine();
			Console.WriteLine("  -i, --ignore  忽略转换过程错误，不会造成进程终止.");
			Console.WriteLine("                可选参数.");
			Console.WriteLine();
			Console.WriteLine("示例:");
			Console.WriteLine(@" MailConverter.exe to-mime --ignore C:\input\* C:\output");
			Console.WriteLine(@" MailConverter.exe to-msg --ignore C:\input\* C:\output");
			Console.WriteLine(@" MailConverter.exe to-mime C:\input\*.msg C:\output");
			Console.WriteLine(@" MailConverter.exe to-msg C:\input\*.eml C:\output");
			Console.WriteLine(@" MailConverter.exe to-mime C:\input\mail.msg C:\output");
			Console.WriteLine(@" MailConverter.exe to-msg C:\input\mail.eml C:\output");
			Console.WriteLine();
			Console.WriteLine("退出代码:");
			Console.WriteLine(" 0 - 已成功转换所有文件.");
			Console.WriteLine(" 1 - 转换未完成 (参数错误).");
			Console.WriteLine(" 2 - 转换出错.");
		}

        /// <summary>
        /// 将单个邮件文件转换为指定的邮件格式.
        /// </summary>
        private static void ConvertSingleFile(string sourceFile, MailFormat format, string targetDir)
		{
			string outputFilename = CreateOutputFilename(sourceFile, format, targetDir);
			Console.Write("  {0} -> {1} ... ", sourceFile, outputFilename);

			MailMessage mail = new MailMessage();
			mail.Load(sourceFile);
			mail.Save(outputFilename, format);
			Console.WriteLine("完成.");
		}

		/// <summary>
		/// 处理应用程序参数.
		/// </summary>
		private static bool TryParseArguments(string[] args)
		{
			if (args == null || args.Length < 3 || args.Length > 4)
				return false;

			// Syntax: MailConverter.exe <format> [options ..] <input> <output>
			string format = args[0];            // first is: <format>
			SourcePath = args[args.Length - 2]; // next-to-last is: <input>
			TargetDir = args[args.Length - 1];  // last is: <output>

            // 处理目标格式参数
            switch (format.ToLowerInvariant())
			{
				case "to-mime":
					TargetFormat = MailFormat.Mime;
					break;

				case "to-msg":
					TargetFormat = MailFormat.OutlookMsg;
					break;

				default:
					Console.WriteLine();
					Console.WriteLine("指定格式无效: {0}.", format);
					Console.WriteLine();
					return false;
			}

            // 处理可选参数
            for (int i = 1; i < args.Length - 2; i++)
			{
				switch (args[i].ToLowerInvariant())
				{
					case "-i":
					case "--ignore":
						Ignore = true;
						break;

					default:
						Console.WriteLine();
						Console.WriteLine("未知参数: {0}.", args[i]);
						Console.WriteLine();
						return false;
				}
			}

			return true;
		}

        /// <summary>
        /// 创建目标文件名,一般取自源文件名,
        /// 扩展名派生自目标格式.
        /// </summary>
        private static string CreateOutputFilename(string sourceFile, MailFormat format, string targetDir)
		{
			string basename = Path.GetFileNameWithoutExtension(sourceFile);
			string extension = GetFileExtensionFromMailFormat(format);

			return Path.Combine(targetDir, basename + extension);
		}

        /// <summary>
        /// 创建邮件文件扩展名.
        /// </summary>
        private static string GetFileExtensionFromMailFormat(MailFormat format)
		{
			switch (format)
			{
				case MailFormat.Mime: return ".eml";
				case MailFormat.OutlookMsg: return ".msg";
				default: throw new NotSupportedException(string.Format("输出文件格式 '{0}' 不受支持.", format));
			}
		}
	}
}
